package com.yxw.yx_hotel.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yxw.yx_hotel.dto.QueryRoomReportDto;
import com.yxw.yx_hotel.dto.QueryStayReportDto;
import com.yxw.yx_hotel.entity.YxReportTitelEntity;
import com.yxw.yx_hotel.mapper.ReportMapper;
import com.yxw.yx_hotel.mapper.ReportTitelMapper;
import com.yxw.yx_hotel.service.ReportService;
import com.yxw.yx_hotel.utils.EasypoiExcelUtil;
import com.yxw.yx_hotel.utils.PageUtils;
import com.yxw.yx_hotel.utils.UserUtil;
import com.yxw.yx_hotel.vo.ReportRoomVo;
import com.yxw.yx_hotel.vo.ReportStayVo;
import com.yxw.yx_hotel.vo.ReportTitelVo;
import com.yxw.yx_hotel.vo.UserTokenVo;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.exception.BaseException;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  报表管理
 * @author liuxin
 * @date 2024.01.22
 */
@Service
public class ReportServiceImpl  implements ReportService {

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private UserUtil userUtil;

    @Autowired
    private ReportTitelMapper reportTitelMapper;



    /**
     * 查询宿舍统计列表
     * @param dto
     * @return
     */
    @Override
    public PageVO<ReportRoomVo> pageRoomReportList(QueryRoomReportDto dto) {
        UserTokenVo userVo = userUtil.getLoginUserVo();
        dto.setTenantId(userVo.getTenantId());
        Page<ReportRoomVo> page = new Page<>(dto.getCurrPage(),dto.getPageSize());
        List<ReportRoomVo> voList=reportMapper.pageRoomReportList(page,dto);
        return PageUtils.get(page, voList);
    }

    /**
     * 宿舍报表数据导出
     * @param response
     * @param dto
     */
    @Override
    public void exportRoomData(HttpServletResponse response, QueryRoomReportDto dto) {
        try {
            List<Long> titelIdList = dto.getTitelIdList();
            if (null == titelIdList || titelIdList.isEmpty()) {
                throw new BaseException("报表标题不能为空");
            }
            LambdaQueryWrapper<YxReportTitelEntity> titelWrapper = new LambdaQueryWrapper();
            titelWrapper.in(YxReportTitelEntity::getTitelId, titelIdList);
            titelWrapper.orderByAsc(YxReportTitelEntity::getSort);
            List<YxReportTitelEntity> titelList = reportTitelMapper.selectList(titelWrapper);
            if (null == titelList || titelList.isEmpty()) {
                throw new BaseException("未查询到报表标题信息");
            }
            //查询数据
            UserTokenVo userVo = userUtil.getLoginUserVo();
            dto.setTenantId(userVo.getTenantId());
            List<ReportRoomVo> voList = reportMapper.pageRoomReportList(null, dto);
            if (null == voList || voList.isEmpty()) {
                throw new BaseException("没有可导出数据");
            }
            List<ExcelExportEntity> colList = new ArrayList<>();
            for (int i = 0; i < titelList.size(); i++) {
                YxReportTitelEntity titelEntity = titelList.get(i);
                colList.add(new ExcelExportEntity(titelEntity.getTitelName(), titelEntity.getFieldName()));
            }
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < voList.size(); i++) {
                Map<String, Object> valMap = new HashMap<String, Object>();
                for (int j = 0; j < titelList.size(); j++) {
                    String fieldName = titelList.get(j).getFieldName();
                    ReportRoomVo reportRoomVo = voList.get(i);
                    //反射通过方法名组装字段
                    Class<? extends ReportRoomVo> clazz = reportRoomVo.getClass();
                    Method[] methods = clazz.getDeclaredMethods();// 获取所有方法
                    for (Method method : methods) {
                        if (method.getName().startsWith("get") && method.getName().toLowerCase().contains(fieldName.toLowerCase())) {
                            //获取字段名称
                            Field field = clazz.getDeclaredField(fieldName);
                            //设置可读
                            field.setAccessible(true);
                            Object value = field.get(reportRoomVo);
                            if(null==value){
                                valMap.put(fieldName,null);
                            }else{
                                valMap.put(fieldName,value);
                            }
                        }
                    }
                }
                list.add(valMap);
            }
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("宿舍报表信息", "宿舍报表信息"), colList,list);
            String fileName=new String ("宿舍报表信息".getBytes(StandardCharsets.UTF_8));
            EasypoiExcelUtil.downLoadExcel(fileName,response,workbook);
        }catch (Exception e){
           throw new BaseException(e.getMessage());
        }
    }

    /**
     * 查询住宿统计列表
     * @param dto
     * @return
     */
    @Override
    public PageVO<ReportStayVo> pageStayReportList(QueryStayReportDto dto) {
        UserTokenVo userVo = userUtil.getLoginUserVo();
        dto.setTenantId(userVo.getTenantId());
        Page<ReportStayVo> page = new Page<>(dto.getCurrPage(),dto.getPageSize());
        List<ReportStayVo> voList=reportMapper.pageStayReportList(page,dto);
        return PageUtils.get(page, voList);
    }

    /**
     * 住宿报表数据导出
     * @param response
     * @param dto
     */
    @Override
    public void exportStayData(HttpServletResponse response, QueryStayReportDto dto) {
        try {
            List<Long> titelIdList = dto.getTitelIdList();
            if (null == titelIdList || titelIdList.isEmpty()) {
                throw new BaseException("报表标题不能为空");
            }
            LambdaQueryWrapper<YxReportTitelEntity> titelWrapper = new LambdaQueryWrapper();
            titelWrapper.in(YxReportTitelEntity::getTitelId, titelIdList);
            titelWrapper.orderByAsc(YxReportTitelEntity::getSort);
            List<YxReportTitelEntity> titelList = reportTitelMapper.selectList(titelWrapper);
            if (null == titelList || titelList.isEmpty()) {
                throw new BaseException("未查询到报表标题信息");
            }
            //查询数据
            UserTokenVo userVo = userUtil.getLoginUserVo();
            dto.setTenantId(userVo.getTenantId());
            List<ReportStayVo> voList = reportMapper.pageStayReportList(null, dto);
            if (null == voList || voList.isEmpty()) {
                throw new BaseException("没有可导出数据");
            }
            List<ExcelExportEntity> colList = new ArrayList<>();
            for (int i = 0; i < titelList.size(); i++) {
                YxReportTitelEntity titelEntity = titelList.get(i);
                colList.add(new ExcelExportEntity(titelEntity.getTitelName(), titelEntity.getFieldName()));
            }
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            for (int i = 0; i < voList.size(); i++) {
                Map<String, Object> valMap = new HashMap<String, Object>();
                for (int j = 0; j < titelList.size(); j++) {
                    String fieldName = titelList.get(j).getFieldName();
                    ReportStayVo stayVo = voList.get(i);
                    //反射通过方法名组装字段
                    Class<? extends ReportStayVo> clazz = stayVo.getClass();
                    Method[] methods = clazz.getDeclaredMethods();// 获取所有方法
                    for (Method method : methods) {
                        if (method.getName().startsWith("get") && method.getName().toLowerCase().contains(fieldName.toLowerCase())) {
                            //获取字段名称
                            Field field = clazz.getDeclaredField(fieldName);
                            //设置可读
                            field.setAccessible(true);
                            Object value = field.get(stayVo);
                            if(null==value){
                                valMap.put(fieldName,null);
                            }else{
                                valMap.put(fieldName,value);
                            }
                        }
                    }
                }
                list.add(valMap);
            }
            Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("住宿报表信息", "住宿报表信息"), colList,list);
            String fileName=new String ("住宿报表信息".getBytes(StandardCharsets.UTF_8));
            EasypoiExcelUtil.downLoadExcel(fileName,response,workbook);
        }catch (Exception e){
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 查询报表标题
     * @param titelType
     * @return
     */
    @Override
    public List<ReportTitelVo> getTitelList(Integer titelType) {
        List<ReportTitelVo> voList=new ArrayList<>();
        LambdaQueryWrapper<YxReportTitelEntity> queryWrapper=new LambdaQueryWrapper();
        queryWrapper.eq(YxReportTitelEntity::getTitelType,titelType);
        queryWrapper.orderByAsc(YxReportTitelEntity::getSort);
        List<YxReportTitelEntity> entityList = reportTitelMapper.selectList(queryWrapper);
        if(null!=voList){
            voList=BeanUtil.copyToList(entityList,ReportTitelVo.class);
        }
        return voList;
    }
}
